{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5ce2c230",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Tuple\n",
    "# A tuple is a fixed-length, immutable sequence of Python objects.\n",
    "tup = 4,5,6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c37bdbc2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 5, 6)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "94b6a793",
   "metadata": {},
   "outputs": [],
   "source": [
    "nested_tup = (4,5,6),(7,8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "48aec1aa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((4, 5, 6), (7, 8))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nested_tup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2eb41b67",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 0, 2)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Convert sequence or iterator to a tuple by invoking tuple\n",
    "# sequence\n",
    "tuple([4,0,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f4468ce9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# iterator\n",
    "tup = tuple('string')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7e498a47",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('s', 't', 'r', 'i', 'n', 'g')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b7e9b994",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'s'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Elements access\n",
    "tup[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8fddd10f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, None, 'foo', 6, 0, 'bar')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# concatenate tuples\n",
    "(4,None,'foo') + (6,0) + ('bar',)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "64df861e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'bar')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# multiplying a tuple by an integer\n",
    "('foo','bar') * 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9d9c0aad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Unpacking tuples\n",
    "# assign tuple to a tuple-like expression of variables, python will attemp to unpack the tuple\n",
    "tup = (4,5,6)\n",
    "a,b,c = tup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "cc4365bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a61508d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# swap variables names\n",
    "a,b = 1,2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "60a5b36e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "768830c1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "6e1e819d",
   "metadata": {},
   "outputs": [],
   "source": [
    "b,a = a,b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "e5815064",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "87f23fc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "bc15555c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a=1, b=2, c=3\n",
      "a=4, b=5, c=6\n",
      "a=7, b=8, c=9\n"
     ]
    }
   ],
   "source": [
    "# variable unpacking\n",
    "# iterating over sequences of tuples or lists\n",
    "\n",
    "# sequence of tuples\n",
    "seq = [(1,2,3),(4,5,6),(7,8,9)]\n",
    "for a,b,c in seq:\n",
    "    print('a={0}, b={1}, c={2}'.format(a,b,c))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "9dd5ea83",
   "metadata": {},
   "outputs": [],
   "source": [
    "# returning multiple values from a function "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "238be189",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function signature 是指“函数名 + 参数列表” add(a,b)\n",
    "def add(a,b):\n",
    "    return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d22d84d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# positional arguments 位置参数 指的是 按顺序传入的参数\n",
    "def greet(name,message):\n",
    "    print (message,name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6e44c919",
   "metadata": {},
   "outputs": [],
   "source": [
    "values = 1,2,3,4,5\n",
    "# unpacking tuples, the special syntax *rest\n",
    "a,b,*rest = values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b832dacb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 2)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a,b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "de19e43a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 4, 5]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "1335e849",
   "metadata": {},
   "outputs": [],
   "source": [
    "# use underscore(_) for unwanted variables\n",
    "a,b,*_ = values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "66df3a1d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Tuple methods\n",
    "# count the number of the occurrences of a value\n",
    "a = (1,2,2,2,3,4,2)\n",
    "a.count(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "7d8e993e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# List\n",
    "# lists are variable-length(可变长度) and their contents can be modified in-place（在原对象的内存地址上\n",
    "# 直接修改数据内容，不创建新的对象）.\n",
    "\n",
    "# define\n",
    "a_list = [2,3,7,None]\n",
    "tup = ('foo','bar','baz')\n",
    "# using the list type function\n",
    "b_list = list(tup)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "8f397bef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'bar', 'baz']"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "c4d7d9f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# contents can be modified in-place\n",
    "b_list[1] = 'peekaboo'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "92cab70c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'peekaboo', 'baz']"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "8f820eda",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Lists and tuples area semantically similar(语义上相似)\n",
    "# List function\n",
    "# materialize an iterator or generator expression\n",
    "gen = range(10)\n",
    "list(gen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "1d7b6e2e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'peekaboo', 'baz', 'dwr']"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# adding and removing elements\n",
    "\n",
    "# append method\n",
    "# elements can be appended to the end of the list.\n",
    "b_list.append('dwr')\n",
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "1d36c592",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'red', 'peekaboo', 'baz', 'dwr']"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# insert method\n",
    "# insert an element at a specific location in the list\n",
    "# insertion index between 0 and the length of the list\n",
    "b_list.insert(1,'red')\n",
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "d4340e12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'red', 'baz', 'dwr']"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# pop method\n",
    "# the inverse operation to insert, removes and returns an element at a particular index\n",
    "b_list.pop(2)\n",
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "e7491be8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['foo', 'red', 'baz', 'dwr', 'foo']"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# remove method\n",
    "# remove elements, locates the first such value and removes it from the list\n",
    "b_list.append('foo')\n",
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "0ec2f226",
   "metadata": {},
   "outputs": [],
   "source": [
    "b_list.remove('foo')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "ecca77b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'baz', 'dwr', 'foo']"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "36cf3426",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check if a list contains a value using the in keyword.\n",
    "'dwr' in b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "959460c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# keyword not \n",
    "'dwr' not in b_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "e8b703be",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4, None, 'foo', 7, 8, (2, 3)]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# concatenating and combining lists\n",
    "[4,None,'foo'] + [7,8,(2,3)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "52a6aa42",
   "metadata": {},
   "outputs": [],
   "source": [
    "# extend method, append multiple elements to a list\n",
    "x = [4,None,'foo']\n",
    "x.extend([7,8,(2,3)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "169c3e88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4, None, 'foo', 7, 8, (2, 3)]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f187c96b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 5, 7]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Sorting\n",
    "# sort a list in-place by calling its sort funtion\n",
    "a = [7,2,5,1,3]\n",
    "a.sort()\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "c52d3578",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['He', 'saw', 'six', 'small', 'foxes']"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sort key -- a function that produces a value to use to sort the objects.\n",
    "b = ['saw', 'small', 'He', 'foxes', 'six']\n",
    "b.sort(key=len)\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "d5ac8370",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 2, 2, 3, 4, 6, 7]"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# binary search and maintaining a sorted list\n",
    "import bisect\n",
    "c = [1, 2, 2, 2, 3, 4, 7]\n",
    "bisect.bisect(c,2)\n",
    "bisect.bisect(c,5)\n",
    "bisect.insort(c,6)\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f7a48289",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 3, 7, 5]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Slicing\n",
    "# select sections of most sequence types\n",
    "# its basic form consist of start:stop\n",
    "# the element at the start index is included,the stop index is not included.\n",
    "# the number of elements in the result is stop - start\n",
    "seq = [7, 2, 3, 7, 5, 6, 0, 1]\n",
    "seq[1:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "d8e5f21d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 2, 3, 6, 3, 6, 0, 1]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Slices can be assigned to with a sequence\n",
    "seq[3:5] = [6,3]\n",
    "seq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "9f1193da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 2, 3, 6, 3]"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Either the start and stop can be omitted.\n",
    "# in which case the default to the start of the sequence and the end of the sequence.\n",
    "seq[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "7492c532",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[6, 3, 6, 0, 1]"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seq[3:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "c6f09758",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 6, 0, 1]"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Negative indices slice the sequence relative to the end.\n",
    "seq[-4:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "0fa26ce8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 6, 3, 6, 0, 1]"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seq[-6:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "c55df98b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 6, 3, 6]"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seq[-6:-2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "2fbb437c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 2, 3, 6, 3, 6, 0, 1]"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# index 0 -> 7 or -1 -> -8\n",
    "seq[-8:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "c35cd819",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 3, 3, 0]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a step can be used after a second colon, say, take every other（每隔一个） element:\n",
    "seq[::2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "41c2534b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 2, 3, 6, 3, 6, 0, 1]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seq[::1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "fc26cd0d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 0, 6, 3, 6, 3, 2, 7]"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# step = -1 也就是\"反向\"取元素\n",
    "seq[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "b8749d25",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 apple\n",
      "1 pear\n",
      "2 banana\n"
     ]
    }
   ],
   "source": [
    "# build-in sequence functions\n",
    "# enumerate\n",
    "# return a sequece of (i, value) tuples.\n",
    "\n",
    "# 1.iterating over a sequence\n",
    "# 2.keep track of the index of the current item\n",
    "fruits = ['apple','pear','banana']\n",
    "for index, fruit in enumerate(fruits):\n",
    "    print(index,fruit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "ec7bfd42",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 apple\n",
      "1 pear\n",
      "2 banana\n"
     ]
    }
   ],
   "source": [
    "# pure python\n",
    "i=0\n",
    "for fruit in fruits:\n",
    "    print(i,fruit)\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "60a8074a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'foo': 0, 'bar': 1, 'baz': 2}"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Python中 dict的本质就是一种“映射结构” mapping type.\n",
    "# dict : mapping key to value.\n",
    "# computing a dict mapping the values of a sequence to their locations in the sequence.\n",
    "# dict-key: the values of a sequence\n",
    "# dict-value: their locations in the sequence.\n",
    "some_list = ['foo', 'bar', 'baz']\n",
    "mapping = {}\n",
    "\n",
    "for i,v in enumerate(some_list):\n",
    "    mapping[v] = i\n",
    "mapping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "b7737e35",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 2, 3, 6, 7]"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sorted function\n",
    "# returns a sorted list from the elements of any sequence.\n",
    "sorted([7, 1, 2, 6, 0, 3, 2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "c2719dc4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# zip function\n",
    "# zip \"pairs\" up the elements of sequences(lists, tuples, or other sequences) to create a list of tuples.\n",
    "seq1 = ['foo', 'bar', 'baz']\n",
    "seq2 = ['one', 'two', 'three']\n",
    "zipped = zip(seq1, seq2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "fa3e58ce",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('foo', 'one'), ('bar', 'two'), ('baz', 'three')]"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(zipped)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "0ff8589e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0: foo,one\n",
      "1: bar,two\n",
      "2: baz,three\n"
     ]
    }
   ],
   "source": [
    "# the common use of zip\n",
    "# simultaneously iterating over multiple sequences, also combined with enumerate\n",
    "for i, (a,b) in enumerate(zip(seq1, seq2)):\n",
    "    print('{0}: {1},{2}'.format(i,a,b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "ab7f8592",
   "metadata": {},
   "outputs": [],
   "source": [
    "# unzip the \"zipped\" sequence\n",
    "# convern a list of rows into a list of columns\n",
    "\n",
    "# a list of rows\n",
    "pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'), ('Curt', 'Schilling')]\n",
    "first_names, last_names = zip(*pitchers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "892f8e1a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('Nolan', 'Roger', 'Curt')"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a list of columns\n",
    "first_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "8b54ebce",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('Ryan', 'Clemens', 'Schilling')"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a list of columns\n",
    "last_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "dd5759a5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# reversed\n",
    "# iterates over the elements of a sequence in reverse order\n",
    "\n",
    "list(reversed(range(10)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "f8b9b0b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# reversed is a generator\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "8728b9e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# dict\n",
    "# a dict is an unordered collection of key-value pairs.\n",
    "empty_dict = {}\n",
    "d1 = {'a' : 'xxx', 'b': [1,2,3,4]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "45c2ea94",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'xxx', 'b': [1, 2, 3, 4]}"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "6247fd7d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# insert element\n",
    "d1[7] = 'an integer'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "cabe6991",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'xxx', 'b': [1, 2, 3, 4], 7: 'an integer'}"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "1bd2668f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4]"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# access element\n",
    "d1['b']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "ebf19eb2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check if a dict contains a key\n",
    "'b' in d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "id": "f7e440a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# delete values\n",
    "# del or pop\n",
    "d1[5] = 'some value'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "97385886",
   "metadata": {},
   "outputs": [],
   "source": [
    "d1['dummy'] = 'another value'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "5b13f4c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'xxx',\n",
       " 'b': [1, 2, 3, 4],\n",
       " 7: 'an integer',\n",
       " 5: 'some value',\n",
       " 'dummy': 'another value'}"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "12c6b9bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "del d1[5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "2166b991",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pop\n",
    "ret = d1.pop('dummy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "e381e2ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'another value'"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "07c97066",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'xxx', 'b': [1, 2, 3, 4], 7: 'an integer'}"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "9f32b9dd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 7]"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# iterators of dict's keys and values\n",
    "# keys method\n",
    "list(d1.keys())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "b7f8b7fe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['xxx', [1, 2, 3, 4], 'an integer']"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# values method\n",
    "list(d1.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "16e54c53",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 'xxx', 'b': 'foo', 7: 'an integer', 'c': 12}"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# merge one dict into another\n",
    "d1.update({'b' : 'foo', 'c' : 12})\n",
    "d1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ee722645",
   "metadata": {},
   "outputs": [],
   "source": [
    "# creating dicts from sequences\n",
    "# tow sequences that you want to pair up element-wise in a dict.\n",
    "# a dict is essentially a collection of 2-tuple(a tuple only has tow values).\n",
    "\n",
    "# dict function: accept a list of 2-tuples.\n",
    "mapping = dict(zip(range(5),reversed(range(5))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7283ce82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: 4, 1: 3, 2: 2, 3: 1, 4: 0}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mapping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3e50ee06",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# default values\n",
    "words = ['apple', 'bat', 'bar', 'atom', 'book']\n",
    "by_letter = {}\n",
    "\n",
    "for word in words:\n",
    "    letter = word[0]\n",
    "    if letter not in by_letter:\n",
    "        by_letter[letter] = [word]\n",
    "    else:\n",
    "        by_letter[letter].append(word)\n",
    "\n",
    "by_letter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "76582c33",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# use setdefault dict method to simplify this workflow\n",
    "# default values\n",
    "words = ['apple', 'bat', 'bar', 'atom', 'book']\n",
    "by_letter = {}\n",
    "\n",
    "for word in words:\n",
    "    letter = word[0]\n",
    "    by_letter.setdefault(letter, []).append(word)\n",
    "\n",
    "by_letter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "234c58c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# build-in collections modules has a defaultdict class.\n",
    "# pass a type or function for generating the default value for each slot in the dict.\n",
    "from collections import defaultdict\n",
    "words = ['apple', 'bat', 'bar', 'atom', 'book']\n",
    "# list is a type ?\n",
    "by_letter = defaultdict(list)\n",
    "\n",
    "for word in words:\n",
    "    by_letter[word[0]].append(word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "947862ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defaultdict(list, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "by_letter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8ff4cb48",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-7916797342462447460"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# valid dict key types\n",
    "# the keys of dict have to be immuable objects. like scalar types or tuples. \n",
    "# Technical term : hashability.\n",
    "# check wheteher an object is hashable with hash function\n",
    "hash('string')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "558d4c18",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-9209053662355515447"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hash((1,2,(2,3)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e7479f1e",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'list'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[6], line 2\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[38;5;66;03m# fails because lists are mutable\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;43mhash\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "# fails because lists are mutable\n",
    "hash((1,2,[2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "8fd0585d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(1, 2, 3): 5}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# to use a list as a key.\n",
    "# convert it to a tuple\n",
    "d = {}\n",
    "d[tuple([1,2,3])] = 5\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e6623c9b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a set is an unordered collection of unique elements.\n",
    "# A set can be created in two ways:\n",
    "# via set function\n",
    "set([2,2,3,1,1,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d6b14dce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#via a set literal with curly braces\n",
    "# literal : 字面量，即在代码中直接写出得值（不是变量或计算结果）\n",
    "# with curly braces: 用花括号\n",
    "{2,2,3,1,1,2,3}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "27acc72a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# sets mathematical set operations\n",
    "a = {1, 2, 3, 4, 5}\n",
    "b = {3, 4, 5, 6, 7, 8}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "19b0ec3f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5, 6, 7, 8}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# union method or the | binary operator\n",
    "# the union of these sets is the set of distinct elements occurring in either set\n",
    "a.union(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "171825e6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5, 6, 7, 8}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a | b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "35ab2cf5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{3, 4, 5}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# intersection method or the & operator\n",
    "# the intersection contains the elements occurring in both sets.\n",
    "a.intersection(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cfee2e8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{3, 4, 5}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a & b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "69eedb2e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(1, 2, 3, 4)}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# like a dict's keys, a set's elements generally must be immutable, and they must be hashable.\n",
    "# in order to store list-like elements(or other muatable sequence) in a set, you can convert them to tuples.\n",
    "my_data = [1,2,3,4]\n",
    "my_set = {tuple(my_data)}\n",
    "my_set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d5e12189",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check if a subset or superset\n",
    "a_set = {1,2,3,4,5}\n",
    "{1,2,3}.issubset(a_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "5fb960c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a_set.issuperset({1,2,3})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "2a3f51b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sets area equal if and only their contents are equal\n",
    "{1,2,3} == {3,2,1}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0394deab",
   "metadata": {},
   "outputs": [],
   "source": [
    "# List, Set, Dict Comprehensions\n",
    "# List Comprehensions form a list by filtering the elements of a collection, transforming the elements passing\n",
    "# the filter in one concise expression.\n",
    "strings = ['a', 'as', 'bat', 'car', 'dove', 'python']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e42983a2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['BAT', 'CAR', 'DOVE', 'PYTHON']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# filtering: len(x) > 2\n",
    "# transforming: x.upper()\n",
    "[x.upper() for x in strings if len(x) > 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b986bf3e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set and dict comprehensions\n",
    "# A dict comprehension: \n",
    "# dict_comp = [key-expr : value-expr for value in collection if condition]\n",
    "\n",
    "# A set comprehension:\n",
    "# set_comp = [expr for value in collecion if condition]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "24690b8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 6}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a set containing just the lengths of the strings contained in the collection\n",
    "unique_lengths = {len(x) for x in strings}\n",
    "unique_lengths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0d882847",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 6}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# using the map function\n",
    "set(map(len,strings))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a783280a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a lookup map of these strings to their locations in the list\n",
    "loc_mapping = {val : index for index, val in enumerate(strings)}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d9164f92",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loc_mapping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a8be0a99",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Nested list comprehensions\n",
    "# a list of list\n",
    "all_data = [['John', 'Emily', 'Michael', 'Mary','Steven'],['Maria', 'Juan', 'Javier', 'Natalia','Pilar']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "26d8608f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get a single list containing all names with two or more a's in them\n",
    "names_of_interest = []\n",
    "for names in all_data:\n",
    "    enough_as = [name for name in names if name.count('a') >= 2]\n",
    "    names_of_interest.extend(enough_as)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2debc11b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Maria', 'Natalia']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names_of_interest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "8119cd2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# wrap this whole operation up in a single nested list\n",
    "result = [name for names in all_data for name in names if name.count('a') >= 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1f0939c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Maria', 'Natalia']"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "bb58c010",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The for parts of the list comprehension are arranged according to the order of nesting.\n",
    "# the order of nesting: 外层在前，内层在后\n",
    "\n",
    "# \"flatten\" a list of tuples of integers into a simple list of integers\n",
    "some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]\n",
    "# the order of for expression would be the same if you wrote a nested for loop instead of a list comprehension.\n",
    "flattened = [x for tup in some_tuples for x in tup]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "cbe43a32",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "flattened"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "99d9d92f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# a list comprehension inside a list comprehension\n",
    "# this produces a list of list\n",
    "[[x for x in tup] for tup in some_tuples]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "521b2289",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
